﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Common.Views;
using Common;
using DataAccess;
using iTextSharp.text;

namespace BusinessLogic
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "OrdersService" in code, svc and config file together.
    /// <summary>
    /// This service contains methods which send and get data regarding orders to and
    /// from the Orders and OrderDetails tables in the database.
    /// </summary>
    public class OrdersService : IOrdersService
    {
        /// <summary>
        /// A method used to create a new order for a particular user
        /// </summary>
        /// <param name="username">The username of the user placing the order</param>
        /// <param name="orderID">The ID of the order (GUID)</param>
        /// <param name="products">A list of the products bought</param>
        public void PlaceOrder(string username, Guid orderID, List<CartView> products)
        {
            OrdersRepository or = new OrdersRepository();
            ProductsRepository pr = new ProductsRepository();
            or.Entity = pr.Entity;

            Order o = new Order();
            o.OrderID = orderID;
            o.Username = username; 
            o.OrderDate = DateTime.Now;
            
            OrderDetail od;

            try
            {
                or.Entity.Connection.Open();
                or.Transaction = pr.Transaction = or.Entity.Connection.BeginTransaction();

                or.AddOrder(o);

                foreach (CartView p in products)
                {
                    od = new OrderDetail();
                    od.OrderID = orderID;
                    od.ProductID = p.ProductID;
                    od.ProductQty = p.ProductQuantity;
                    DateTime wed = DateTime.Now;
                    od.WarrantyExpiryDate = wed.AddYears(+2);

                    or.AddOrderDetails(od);
                    pr.DecreaseStock(p.ProductID, p.ProductQuantity);
                }

                foreach (Cart sc in pr.GetCartForUser(username))
                {
                    pr.RemoveShoppingCart(sc);
                }
                                
                or.Transaction.Commit();
            }
            catch (Exception ex)
            {
                or.Transaction.Rollback();
            }
            finally
            {
                or.Entity.Connection.Close();
            }
        }

        /// <summary>
        /// A method which retrieves a list of all the products bought by a particular user
        /// </summary>
        /// <param name="username">The username of the user for which to get the list of products</param>
        /// <returns>A list of the products bought by the particular username</returns>
        public IEnumerable<OrdersView> GetProductsBoughtByUser(string username)
        {
            return new OrdersRepository().GetProductsBoughtByUser(username);
        }

        /// <summary>
        /// A method which gets the most purchased item
        /// </summary>
        /// <returns>A list of details of the most purchased item</returns>
        public IEnumerable<StatisticalView> MostPurchasedItem()
        {
            return new OrdersRepository().MostPurchasedItem();
        }

        /// <summary>
        /// A method which gets the highly rated item
        /// </summary>
        /// <returns>A list of details of the highly rated item</returns>
        public IEnumerable<StatisticalView> HighlyRatedItem()
        {
            return new OrdersRepository().HighlyRatedItem();
        }

        /// <summary>
        /// A list of products with the highest number of faults
        /// </summary>
        /// <returns>A list of the products with the highest number of faults and their details</returns>
        public IEnumerable<StatisticalView> HighestNumOfFaults()
        {
            return new OrdersRepository().HighestNumOfFaults();
        }

        /// <summary>
        /// A list of products with the least number of faults
        /// </summary>
        /// <returns>A list of the products with the least number of faults and their details</returns>
        public IEnumerable<StatisticalView> LeastNumOfFaults()
        {
            return new OrdersRepository().LeastNumOfFaults();
        }

        /// <summary>
        /// A method which is used to send the order details to a user
        /// </summary>
        /// <param name="username">The username of the user whom to send the order details</param>
        public void SaveDetails(string username)
        {
            new OrdersRepository().SaveDetails(username);
        }
    }
}
